package cn.com.sinux.spring.utils;

/**
 * Created with IntelliJ IDEA.
 * User: New
 * Date: 13-4-1
 * Time: 下午3:46
 * To change this template use File | Settings | File Templates.
 */

import cn.com.sinux.spring.commons.ImageCropHelper;
import cn.com.sinux.spring.utils.image.ImageTransform;
import cn.com.sinux.spring.utils.image.ImageTransformFactory;
import org.apache.commons.lang.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

/**
 * 图片处理工具类：<br>
 * 功能：缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
 *
 * @author Administrator
 */
public class ImageUtils {

    private static final Integer FONT_PLAIN = Font.PLAIN;
    private static final Integer FONT_BOLDER = Font.BOLD;
    private static final Integer FONT_ITALIC = Font.ITALIC;

    private static final java.util.List<String> imageTypeCollections = Arrays.asList(new String[]{
            "jpg", "png", "gif", "bmp"
    });

    /**
     * use imageTransform to resize,rotate image.
     *
     * @param srcFilePath  源文件路径,eg D:\\ccs\\web\\upload_images\\original\\1.jpg
     * @param destFilePath 目标文件路径,eg D:\\ccs\\web\\upload_images\\big\\1.jpg
     * @param width        宽度
     * @param height       高度
     * @throws Exception Exception
     */
    public static void resizeImage(BufferedImage bufferedImage,String srcFilePath, String destFilePath, int width, int height) throws Exception {
        ImageTransform it = ImageTransformFactory.getImageTransform();
        if (it.load(bufferedImage,srcFilePath)) {
            it.resize(width, height);
            it.save(destFilePath);
        }
    }

    /**
     * 根据最大宽度缩放图片
     *
     * @param srcFilePath  源文件路径,eg D:\\ccs\\web\\upload_images\\original\\1.jpg
     * @param destFilePath 目标文件路径,eg D:\\ccs\\web\\upload_images\\big\\1.jpg
     * @param maxWidth     最大宽度
     * @throws Exception 异常
     */
    public static void resizeImageWithMaxWidth(String srcFilePath, String destFilePath, int maxWidth) throws Exception {
        ImageTransform it = ImageTransformFactory.getImageTransform();
        if (it.load(srcFilePath)) {
            it.resizeWithMaxWidth(maxWidth);
            it.save(destFilePath);
        }

    }

    /**
     * 根据最大宽度缩放图片
     *
     * @param srcFilePath  源文件路径,eg D:\\ccs\\web\\upload_images\\original\\1.jpg
     * @param destFilePath 目标文件路径,eg D:\\ccs\\web\\upload_images\\big\\1.jpg
     * @param rotate       压缩比例
     * @param maxWidth     最大宽度
     * @throws Exception
     */
    public static void rotateImageWithMaxWidth(String srcFilePath, String destFilePath, double rotate, int maxWidth)
            throws Exception {
        ImageTransform it = ImageTransformFactory.getImageTransform();
        if (it.load(srcFilePath)) {
            it.rotateWithMaxWidth(rotate, maxWidth);
            it.save(destFilePath);
        }

    }

    /**
     * 缩放图片
     *
     * @param srcFilePath  源文件路径,eg D:\\ccs\\web\\upload_images\\original\\1.jpg
     * @param destFilePath 目标文件路径,eg D:\\ccs\\web\\upload_images\\big\\1.jpg
     * @param rotate       缩放比例
     * @throws Exception
     */
    public static void rotateImage(String srcFilePath, String destFilePath, double rotate) throws Exception {
        ImageTransform it = ImageTransformFactory.getImageTransform();

        if (it.load(srcFilePath)) {
            it.rotate(rotate);
            it.save(destFilePath);
        }
    }

    /**
     * 以像素为单位截取图像.
     *
     * @param src    源图片路径.
     * @param dest   目标图片路径.
     * @param left   左坐标.
     * @param top    顶坐标.
     * @param width  宽度.
     * @param height 高度.
     */
    public static void cropImage(String src, String dest, int left, int top, int width, int height) {
        ImageTransform it = ImageTransformFactory.getImageTransform();

        if (it.load(src)) {                        // load
            it.crop(left, top, width, height);    // crop
            it.save(dest);                         // save.
        }
    }

    /**
     * 以像素为单位截取图像.
     *
     * @param src  源图片路径.
     * @param dest 目标图片路径.
     */
    public static void cropImage(String src, String dest, ImageCropHelper imageCropHelper) {
        ImageTransform it = ImageTransformFactory.getImageTransform();
        if (imageCropHelper.isCrop()) {
            cropImage(src, dest, imageCropHelper.getX(), imageCropHelper.getY(), imageCropHelper.getWidth(), imageCropHelper.getHeight());
        }else{
            FileUtils.copy(new File(src), new File(dest), false);
        }
    }

    /**
     * 图像类型转换：GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG
     *
     * @param srcImageFile  源图像地址
     * @param formatName    包含格式非正式名称的 String：如JPG、JPEG、GIF等
     * @param destImageFile 目标图像地址
     */
    public static void convert(String srcImageFile, String formatName, String destImageFile) {
        try {
            File f = new File(srcImageFile);
            if (f.canRead() && f.canWrite()) {
                BufferedImage src = ImageIO.read(f);
                ImageIO.write(src, formatName, new File(destImageFile));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 彩色转为黑白
     *
     * @param srcImageFile  源图像地址
     * @param destImageFile 目标图像地址
     */
    public static void gray(String srcImageFile, String destImageFile) {
        try {
            BufferedImage src = ImageIO.read(new File(srcImageFile));
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
            ColorConvertOp op = new ColorConvertOp(cs, null);
            src = op.filter(src, null);
            ImageIO.write(src, "JPEG", new File(destImageFile));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 给图片添加文字水印
     *
     * @param pressText     水印文字
     * @param srcImageFile  源图像地址
     * @param destImageFile 目标图像地址
     * @param fontName      水印的字体名称
     * @param color         水印的字体颜色
     * @param fontSize      水印的字体大小
     * @param x             修正值
     * @param y             修正值
     * @param alpha         透明度：alpha 必须是范围 [0.0, 1.0] 之内（包含边界值）的一个浮点数字
     */
    public static void pressText(String pressText,
                                 String srcImageFile, String destImageFile, String fontName, Color color, int fontSize, int x,
                                 int y, float alpha) {
        try {
            File img = new File(srcImageFile);
            Image src = ImageIO.read(img);
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            BufferedImage image = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);
            g.setColor(color);
            g.setFont(new Font(fontName, FONT_PLAIN, fontSize));
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            // 在指定坐标绘制水印文字
            g.drawString(pressText, (width - (getLength(pressText) * fontSize))
                    / 2 + x, (height - fontSize) / 2 + y);
            g.dispose();
            ImageIO.write(image, "JPEG", new File(destImageFile));// 输出到文件流
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 给图片添加图片水印
     *
     * @param pressImg      水印图片
     * @param srcImageFile  源图像地址
     * @param destImageFile 目标图像地址
     * @param alpha         透明度：alpha 必须是范围 [0.0, 1.0] 之内（包含边界值）的一个浮点数字
     */
    public static void pressImage(String pressImg, String srcImageFile, String destImageFile, float alpha) {
        try {
            File img = new File(srcImageFile);
            Image src = ImageIO.read(img);
            int wideth = src.getWidth(null);
            int height = src.getHeight(null);
            BufferedImage image = new BufferedImage(wideth, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(src, 0, 0, wideth, height, null);
            // 水印文件
            Image src_biao = ImageIO.read(new File(pressImg));
            int wideth_biao = src_biao.getWidth(null);
            int height_biao = src_biao.getHeight(null);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            g.drawImage(src_biao, (wideth - wideth_biao) / 2,
                    (height - height_biao) / 2, wideth_biao, height_biao, null);
            // 水印文件结束
            g.dispose();
            ImageIO.write(image, "JPEG", new File(destImageFile));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 计算text的长度（一个中文算两个字符）
     *
     * @param text
     * @return
     */
    public static int getLength(String text) {
        int length = 0;
        for (int i = 0; i < text.length(); i++) {
            String _tt = text.charAt(i) + "";
            if (_tt.getBytes().length > 1) {
                length += 2;
            } else {
                length += 1;
            }
        }
        return length / 2;
    }

    /**
     * 保存当前访问屏幕
     *
     * @param marginX  x偏移量
     * @param marginY  y偏移量
     * @param type     图片类型
     * @param destPath 目标路径
     */
    public static void saveHtmlToPic(int marginX, int marginY, String type, String destPath) {
        if (StringUtils.isBlank(type) || !imageTypeCollections.contains(type)) {
            return;
        }
        try {
            //获取屏幕大小
            Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
            //截图
            BufferedImage bim = new Robot().createScreenCapture(new Rectangle(marginX, marginY, dim.width, dim.height));
            ImageIO.write(bim, type, new FileOutputStream(destPath));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        pressText("刘海", "F://test/test.png", "F://test/test1.jpg", Font.SANS_SERIF, Color.BLUE, 18, 200, 100, 1);
    }
}